import { Mp3Encoder } from 'lamejs'

export default class {
  constructor(config) {
    this.bitRate    = config.bitRate
    this.sampleRate = config.sampleRate
    this.dataBuffer = []
    this.encoder    = new Mp3Encoder(1, this.sampleRate, this.bitRate)
    this.wsServer = 'wss://10.20.1.57:7777/'; //服务器地址
    this.websocket = new WebSocket(this.wsServer); //创建WebSocket对象
    this.websocket.binaryType = "arraybuffer";
    this.websocket.onopen = function (evt) {
      console.debug("连接成功")
    };
    this.websocket.onclose = function (evt) {
      console.debug("关闭成功")
    };
    this.websocket.onmessage = function (evt) {
      console.debug("收到消息", evt)
    };
    this.websocket.onerror = function (evt) {
      console.debug("遇到错误")
    };
  }

  encode(arrayBuffer) {
    const maxSamples = 1152
    if (arrayBuffer[0] == 0 && arrayBuffer[1] == 0){
      return
    }

    const samples    = this._convertBuffer(arrayBuffer)
    let remaining    = samples.length

    const samples2    = this._myConvertBuffer(arrayBuffer)

    // console.debug("encodeing", samples2)
    // 通过websocket发送至服务器
    this.websocket.send(samples2)

    // 以下是mp3 encoder
    for (let i = 0; remaining >= 0; i += maxSamples) {
      const left = samples.subarray(i, i + maxSamples)
      const buffer = this.encoder.encodeBuffer(left)
      this.dataBuffer.push(new Int8Array(buffer))
      remaining -= maxSamples
    }
  }

  finish() {
    this.dataBuffer.push(this.encoder.flush())
    const blob = new Blob(this.dataBuffer, { type: 'audio/mp3' })
    this.dataBuffer = []

    return {
      id    : Date.now(),
      blob  : blob,
      url   : URL.createObjectURL(blob)
    }
    this.websocket.close()
  }

  _floatTo16BitPCM(input, output) {
    for (let i = 0; i < input.length; i++) {
      const s = Math.max(-1, Math.min(1, input[i]))
      output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF)
    }
  }

  _convertBuffer(arrayBuffer) {
    const data = new Float32Array(arrayBuffer)
    const out = new Int16Array(arrayBuffer.length)
    this._floatTo16BitPCM(data, out)
    return out
  }

  _myConvertBuffer(arrayBuffer) {
    const data = new Float32Array(arrayBuffer)
    const data2 = this.downsampleBuffer(data, 44100, 8000)
    const out = new Int16Array(data2.length)
    const out2 =new Uint8Array(out.length * 2) ;
    this._floatTo16BitPCM(data2, out)
    for (let i =0; i < out.length; i++){
      let s = out[i]
      let a = (s & 0xff00) >> 8
      let b = (s & 0x00FF)
      out2[i*2] = b
      out2[i*2 + 1] = a
    }
    return out2
  }

  downsampleBuffer(buffer, origrate, rate) {
    if (rate == origrate) {
      return buffer;
    }
    if (rate > origrate) {
      throw "downsampling rate show be smaller than original sample rate";
    }

    let sampleRateRatio = origrate / rate; //计算压缩率，注意这里要取整数
    let newLength = Math.round(buffer.length / sampleRateRatio);
    let result = new Float32Array(newLength);
    let offsetResult = 0;
    let offsetBuffer = 0;
    while (offsetResult < result.length) {
      let nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
      let accum = 0,
        count = 0;
      for (let i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
        accum += buffer[i];
        count++;
      }
      result[offsetResult] = accum / count;
      offsetResult++;
      offsetBuffer = nextOffsetBuffer;
    }
    return result;
  }
}
